home *** CD-ROM | disk | FTP | other *** search
/ CD Actual 85 / CD Temático 40 Febrero 2004.iso / DOS / ntfs / user / ntchange.c < prev    next >
Encoding:
C/C++ Source or Header  |  2001-02-15  |  7.0 KB  |  296 lines

  1. /*
  2.  *  ntchange.c
  3.  *
  4.  *  Copyright (C) 1995-1997, 1999 Martin von L÷wis
  5.  *  Copyright (C) 1997 RΘgis Duchesne
  6.  */
  7.  
  8. #ifdef HAVE_CONFIG_H
  9. #include "config.h"
  10. #endif
  11.  
  12. #include <stdio.h>
  13. #ifdef HAVE_GETOPT_H
  14. #include <getopt.h>
  15. #else
  16. #define getopt_long(a,v,o,ol,x)        getopt(a,v,o)
  17. #endif
  18. #ifdef HAVE_UNISTD_H
  19. #include <unistd.h>
  20. #endif
  21. #include <sys/stat.h>
  22. #ifdef HAVE_FCNTL_H
  23. #include <fcntl.h>
  24. #endif
  25. #ifdef HAVE_IO_H
  26. #include <io.h>
  27. #endif
  28. #include <string.h>
  29. #include <stdlib.h>
  30. #include "ntfstypes.h"
  31. #include "struct.h"
  32. #include "util.h"
  33. #include "nttools.h"
  34. #include "inode.h"
  35. #include "super.h"
  36. #include "attr.h"
  37.  
  38. char *short_opts="a:d:W:t:i:A:L:n:V";
  39. #ifdef HAVE_GETOPT_H
  40. struct option options[]={
  41.     {"alloc-clusters",1,0,'a'},
  42.     {"dealloc-clusters",1,0,'d'},
  43.     {"write-inode",1,0,'W'},
  44.     {"truncate",1,0,'t'},
  45.     {"inum",1,0,'i'},
  46.     {"anum",1,0,'A'},
  47.     {"symlink",1,0,'L'},
  48.     {"new-file",1,0,'n'},
  49.     {"version",0,0,'V'},
  50.     {0,0,0,0}
  51. };
  52. #endif
  53.  
  54. void my_perror(const char* msg,int error)
  55. {
  56.     fprintf(stderr,"%s:%s\n",msg,strerror(error));
  57.     exit(1);
  58. }
  59.  
  60. int usage(void)
  61. {
  62.     fprintf(stderr,"ntchange [options]\n"
  63.         "-o offset                 Offset in file\n"
  64.         "-a start size             Allocate cluster range\n"
  65.         "-d start size             Deallocate cluster range\n"
  66.         "-W inum                   Read and write inode inum\n"
  67.         "-t newsize                truncate inode to newsize\n"
  68.         "-i inum                   operate on inode inum\n"
  69.         "-A anum                   operate on attribute anum (80)\n"
  70.         "-L string                 make inode a symlink with value string\n"
  71.         "-n name                   create file name in dir inum\n"
  72.         "-V                        print version\n"
  73.         );
  74.     return 1;
  75. }
  76.  
  77. /* print the file ino on stdout */
  78. void ntfs_change_file(ntfs_inode *ino,char *buf,int offset,int count)
  79. {
  80.     int position;
  81.     ntfs_io io;
  82.     position=0;
  83.     /* write to the unnamed data attribute */
  84.     io.fn_put=0;
  85.     io.fn_get=0;    /* we don't need copyfunctions here */
  86.     io.param=buf;
  87.     io.size=count;
  88.     ntfs_write_attr(ino,ino->vol->at_data,NULL,offset,&io);
  89. }
  90.  
  91. int main(int argc,char *argv[])
  92. {
  93.     int c,error;
  94.     char device[256]={'\0'};
  95.     char *it;
  96.     char *source=0;
  97.     char *name=0;
  98.     void *buf;
  99.     int fsource;
  100.     ntfs_volume *volume;
  101.     ntfs_inode ino;
  102.     int inum=-1;
  103.     int offset=0;
  104.     int alloc_start = -2;
  105.     int alloc_size=0,dealloc_start=-2;
  106.     int Winum=0;
  107.     int truncate=-2,anum=0x80;
  108.     char *symlink=0;
  109.     char *newfile=0;
  110.     struct stat sb;
  111.     extern int optind,opterr;
  112.     extern char* optarg;
  113.     ntfs_attribute *attr;
  114.  
  115.     opterr=1;
  116.     while((c=getopt_long(argc,argv,short_opts,options,NULL))>0)
  117.         switch(c)
  118.         {
  119.         case 'o': offset=strtol(optarg,NULL,0);break;
  120.         case 'a': alloc_start=strtol(optarg,NULL,0);
  121.             alloc_size=strtol(argv[optind++],NULL,0);
  122.             break;
  123.         case 'd': dealloc_start=strtol(optarg,NULL,0);
  124.             alloc_size=strtol(argv[optind++],NULL,0);
  125.             break;
  126.         case 'W': Winum=strtol(optarg,NULL,0);break;
  127.         case 't': truncate=strtol(optarg,NULL,0);break;
  128.         case 'i': inum=strtol(optarg,NULL,0);break;
  129.         case 'A': anum=strtol(optarg,NULL,0);break;
  130.         case 'L': symlink=optarg;break;
  131.         case 'n': newfile=optarg;break;
  132.         case 'V': printf("ntdir " NTFS_VERSION "\n");exit(0);break;
  133.         default: usage();exit(0);
  134.         }
  135.     if(optind+2!=argc){
  136.         usage();
  137.         exit(1);
  138.     }
  139.     source=argv[optind];
  140.     name=argv[optind+1];
  141.     for(it=name+2;*it && *it!='/';it++)
  142.         /*nothing*/;
  143.     if(it!=name+2)
  144.     {
  145.       strcpy(device,"/dev/");
  146.       strncpy(device+5,name+2,(it-name)-2);
  147.       device[(it-name)+3]='\0';
  148.     }
  149.     name=it;
  150.     if(*name=='/')name++;
  151.     volume=ntfs_open_volume(device,0,1,0);
  152.     if(!volume)return 1;
  153.     volume->nct=nct_utf8;
  154.     if(alloc_start!= -2){
  155.         ntfs_cluster_t st = alloc_start;
  156.         error=ntfs_allocate_clusters(volume,&st,&alloc_size,0);
  157.         if(error)my_perror("allocate",error);
  158.         printf("Got range %x+%x\n", 
  159.                (unsigned int)st, alloc_size);
  160.         return 0;
  161.     }
  162.     if(dealloc_start!= -2){
  163.         error=ntfs_deallocate_clusters(volume,dealloc_start,alloc_size);
  164.         if(error)my_perror("deallocate",error);
  165.         return 0;
  166.     }
  167.     if(Winum){
  168.         error=ntfs_init_inode(&ino,volume,Winum);
  169.         if(error)my_perror("winum",error);
  170.         error=ntfs_update_inode(&ino);
  171.         if(error)my_perror("winum",error);
  172.         return 0;
  173.     }
  174.     if(truncate!=-2){
  175.         if(inum==-1){
  176.             usage();
  177.             return 1;
  178.         }
  179.         error=ntfs_init_inode(&ino,volume,inum);
  180.         if(error)my_perror("init",error);
  181.         attr=ntfs_find_attr(&ino,anum,0);
  182.         if(!attr){
  183.             fprintf(stderr,"Inode %x has no attribute %x\n",inum,anum);
  184.             return 1;
  185.         }
  186.         error=ntfs_resize_attr(&ino,attr,truncate);
  187.         if(error)my_perror("resize",error);
  188.         error=ntfs_update_inode(&ino);
  189.         if(error)my_perror("writeback",error);
  190.         return 0;
  191.     }
  192.     if(symlink){
  193.         unsigned short *data;
  194.         int nlen;
  195.         ntfs_attribute* aresult;
  196.         if(inum<0){
  197.             fprintf(stderr,"No inum given to for symlink");
  198.             return 1;
  199.         }
  200.         nlen=strlen(symlink);
  201.         data=malloc(nlen*2+2);
  202.         ntfs_ascii2uni(data,symlink,nlen);
  203.         error=ntfs_init_inode(&ino,volume,inum);
  204.         if(error)my_perror("init",error);
  205.         error=ntfs_create_attr(&ino,volume->at_symlink,0,
  206.                        data,nlen*2,&aresult);
  207.         if(error)my_perror("create symlink",error);
  208.         attr=ntfs_find_attr(&ino,volume->at_standard_information,0);
  209.         NTFS_PUTU8((ntfs_u8*)attr->d.data+8, 0x40);
  210.         error=ntfs_update_inode(&ino);
  211.         if(error)my_perror("writeback",error);
  212.         return 0;
  213.     }
  214.     if(newfile){
  215.         ntfs_inode dir;
  216.         if(inum<0){
  217.             fprintf(stderr,"no dir given for newfile\n");
  218.             return 1;
  219.         }
  220.         error=ntfs_init_inode(&dir,volume,inum); /* FIXME: check for dir */
  221.         if(error)my_perror("init",error);
  222.         error=ntfs_alloc_file(&dir,&ino,newfile,strlen(newfile));
  223.         if(error)my_perror("create new file",error);
  224.         error=ntfs_update_inode(&ino);
  225.         if(error)my_perror("writeback",error);
  226.         error=ntfs_update_inode(&dir);
  227.         if(error)my_perror("directory writeback",error);
  228.         fprintf(stderr,"allocated inode %x\n",ino.i_number);
  229.         /*error=ntfs_dir_add1(&dir,newfile,strlen(newfile),&ino);
  230.         if(error){
  231.             fprintf(stderr,"error %x when modifying directory\n",
  232.                 error);
  233.             return 1;
  234.         }
  235.         */
  236.         return 0;
  237.     }
  238.       
  239.     if(!source)
  240.         return usage();
  241. #ifdef MSDOS
  242.     fsource=open(source,O_RDONLY|O_BINARY);
  243. #else
  244.     fsource=open(source,O_RDONLY);
  245. #endif
  246.     if(fsource==-1)
  247.     {
  248.         perror(source);
  249.         return 1;
  250.     }
  251.     if(fstat(fsource,&sb)!=0)
  252.     {
  253.         perror(source);
  254.         return 1;
  255.     }
  256.     buf=malloc(sb.st_size);
  257.     if(!buf)
  258.     {
  259.         perror(argv[0]);
  260.         return 1;
  261.     }
  262.     if(read(fsource,buf,sb.st_size)!=sb.st_size)
  263.     {
  264.         perror(argv[0]);
  265.         return 1;
  266.     }
  267.     inum=5;
  268.     /* walk the directory tree */
  269.     do{
  270.         char *next;
  271.         error=ntfs_init_inode(&ino,volume,inum);
  272.         if(error)my_perror("init",error);
  273.         if(!name || !*name)break;
  274.         next=strpbrk(name,NTFS_PATH_SEP);
  275.         if(next){
  276.             *next='\0';
  277.             next++;
  278.         }
  279.         inum=ntfs_find_file(&ino,name);
  280.         if(inum==-1){
  281.             printf("%s not found\n",name);
  282.             return 1;
  283.         }
  284.         name=next;
  285.     }while(1);
  286.     ino.i_number=inum;
  287.     ntfs_change_file(&ino,buf,offset,sb.st_size);
  288.     return 0;
  289. }
  290.  
  291. /*
  292.  * Local variables:
  293.  * c-file-style: "linux"
  294.  * End:
  295.  */
  296.